<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			/*在触发 DOM 上的某个事件时，会产生一个事件对象 event，这个对象中包含着所有与事件有关的信息。
			 *包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。例如，鼠标操作导致的事件对象中，会包含鼠标位置的信息，
			 *而键盘操作导致的事件对象中，会包含与按下的键有关的信息。所有浏览器都支持 event 对象，但支持方式不同。*/
			//13.3.1 DOM中的事件对象
			    //兼容 DOM 的浏览器会将一个 event 对象传入到事件处理程序中。
			    //无论指定事件处理程序时使用什么方法（DOM0 级或 DOM2 级），都会传入 event 对象。
		                var btn = document.getElementById("myBtn"); 
						btn.onclick = function(event){ 
						 alert(event.type); //"click" 
						}; 
				//event对象包含与创建它的特定事件有关的属性和方法。触发的事件类型不一样，可用的属性和方法也不一样。
				//所有事件event对象中共同包含的属性和方法如下所示
				      //1.bubbles,事件是否冒泡,布尔值
				      //2.cancelable,表明是否可以取消事件的默认行为,布尔值
				      //3.currentTarget,其事件处理程序当前在处理时间的那个元素
				      //4.defaultPrevented,为true表示已经调用了preventDefault()
				      //5.detail,与事件相关的细节信息
				      //6.eventPhase,调用事件处理程序的阶段：1表示捕获 2表示处于目标 3表示冒泡 
				      //7.target,事件的目标
				      //8.preventDefault() 取消事件的默认行为，如果cancelable是true，则可以使用这个方法
				      //9.stopPropagation() 取消事件的进一步捕获或冒泡。如果bubbles为true，则可以使用这个方法		      
				       
                //在事件处理程序内部，对象 this 始终等于 currentTarget 的值，而 target 则只包含事件的实际目标。
                			function getEle(ele){
								return document.querySelector(ele)
							}
							var EventUtil = {
								addHandler:function(element,type,handler){
									if(element.addEventListener){
									   element.addEventListener(type,handler,false);
									}else if(element.attachEvent){
									   element.attachEvent('on' + type,handler);
									}else{
										element['on' + type] = handler;
									}
								},
								removeHandler:function(element,type,handler){
									if(element.removeEventListener){
										element.removeEventListener(type,handler,false);
									}else if(element.detachEvent){
										element.detachEvent('on' + type,handler);
									}else{
										element['on' + type] = null;
									}
								}
							}
							var handler = function(event){
								console.log(this);
								console.log(event.currentTarget);
								console.log(event.target);
							    console.log(event.currentTarget === this);
							    console.log(event.target === this);
							}
							EventUtil.addHandler(getEle('#box'),'click',handler);//div div div
							EventUtil.addHandler(document.body,'click',handler);//body body div 
							
				    //在需要通过一个函数处理多个事件时，可以使用 type 属性。
				    //只有在事件处理程序执行期间，event 对象才会存在；一旦事件处理程序执行完成，event 对象就会被销毁。
				    
			//13.3.2 IE中的事件对象
			    //与访问 DOM 中的 event 对象不同，要访问 IE 中的 event 对象有几种不同的方式，取决于指定事件处理程序的方法。
			    //在使用 DOM0 级方法添加事件处理程序时，event 对象作为 window 对象的一个属性存在。
			    			var btn = document.getElementById("myBtn"); 
							btn.onclick = function(){ 
								 var event = window.event; 
								 alert(event.type); //"click" 
							}; 
				//如果事件处理程序是使用 attachEvent()添加的，那么就会有一个 event 对象作为参数被传入事件处理程序函数中
				            var btn = document.getElementById("myBtn"); 
							btn.attachEvent('click',function(event){
								alert(event.type);
							})
			    //如果是通过HTML特性指定的事件处理程序，那么还可以通过一个名叫event的变量来访问event对象（与 DOM 中的事件模型相同）。
			                <input type="button" value="Click Me" onclick="alert(event.type)"> 
			                
			    //所有事件对象都会包含如下的属性和方法          
			    	//cancelBubble，默认值为false，但将其设置为true就可以取消事件冒泡（与DOM中的stopPropagation()方法作用相同）
			    	//returnValue，默认值为true，但将其设置为false就可以取消事件的默认行为（与DOM中的preventDefault()方法作用相同）
			    	//srcElement ，事件的目标（与DOM中的target属性相同）
			    	//type，被触发的事件类型
			    	
			    //IE事件处理程序的作用域是根据指定它的方式来确定的，所以不能认为 this 会始终等于事件目标。最好还是使用 event.srcElement 比较保险。
			    			var btn = document.getElementById("myBtn"); 
							btn.onclick = function(){ 
					 			alert(window.event.srcElement === this); //true 
							}; 
							btn.attachEvent("onclick", function(event){ 
					 			alert(event.srcElement === this);//false
					 	   };
			//13.3.3 跨浏览器的事件对象
			    var EventUtil = {
	                    addHandler:function(element,type,handler){
							//添加事件处理程序
							if(element.addEventListener){
								element.addEventListener(type,handler,false);
							}else if(element.attachment){
								element.attachment("on"+type,handler)
							}else{
								element["on"+type] = handler;
							}
						},
						removeHandler:function(element,type,handler){
							//移除事件处理程序
							if(element.removeEventListener){
								element.removeEventListener(type,handler,false);
							}else if(element.detachEvent){
								element.detachEvent("on"+type,handler)
							}else{
								element["on"+type] = null;
							}
						},
						getEvent:function(event){
							//获取事件对象
							return event?event:window.event;
						},
						getTarget:function(event){
							//获取事件目标
							return event.target || srcElement
						},
						preventDefault:function(event){
							//取消事件的默认行为
							if(event.preventDefault){
							    event.preventDefault();
							}else{
								event.returnValue = false;
							}
						},
						stopPropagation:function(event){
							//阻止事件冒泡
							if(event.stopPropagation){
								event.stopPropagation();
							}else{
								event.cancelBubble = true;
							}
						}
				}
		</script>
	</body>
</html>
